package com.excalibur.core.util;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Rewrite CookieUtil
 */
public final class CookieUtil {
	
	private static final Logger logger = LoggerFactory.getLogger(CookieUtil.class);
	private static String SPLITER = "|";
	
	public static String KEY = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
	
	public static final String COOKIE_KEY = "logon";
	public static final String RELOGIN_KEY = "relogon";//是否重新登陆的标志
	public static final String QRCODE_KEY = "qrcode";
	public static final String HEADIMG_KEY = "headImg";//头像cookie
	/**
	 * cookie域
	 */
	public static final String DOMAIN = ".XXXXXX.com";
	
	public static final String COOKIE_SET_TIME = "settime";
	public static final int COOKIE_LIVE_ONE_DAY = 60 * 60 * 24;
	public static final int COOKIE_LIVE_TEN_MINUTS = 60 * 10;
	/**
	 * session级别cookie的时间设置
	 */
	public static final int COOKIE_LIVE_SESSION = -1;
	public static final String CAPTCHA_KEY = "XXXXXXX";
	
	static {
		ResourceBundle rb = null;
		try {
			rb = ResourceBundle.getBundle("cookieSecretKey");
		} catch (RuntimeException e) {
			logger.error("cookieSecretKey.properties not found, will be use default value : "+KEY);
		}
		if(rb != null){
			String secretKey = "";
			try {
				secretKey = rb.getString("cookie.secret.key");
			} catch (RuntimeException e) {
				logger.error("can not found cookie.secret.key in cookieSecretKey.properties, will be use default value : "+KEY);
			}
			if(!StringUtils.isEmpty(secretKey)){
				KEY = secretKey;
			}
			
		}
	}
	
	/**
	 * 添加cookie
	 * @param response
	 * @param domain       域
	 * @param key          键
	 * @param value        值
	 * @param expiry       过期时间[单位：/s]
	 * @return
	 */
	public static boolean setCookie(HttpServletResponse response, String domain, String key, String value, int expiry) {
		try {
			Cookie cookie = new Cookie(key, value); //will be throw new IllegalArgumentException(errMsg);
			cookie.setPath("/"); // very important
			cookie.setDomain(StringUtils.isEmpty(domain)?DOMAIN:domain);
			cookie.setMaxAge(expiry);
			response.setHeader("P3P", "CP=\"IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA\"");
			response.addCookie(cookie);
			return true;
		} catch (IllegalArgumentException e) {
			logger.error(e.getMessage());
			return false;
		}
	}

	/**
	 * 取一个cookie
	 * @param request
	 * @param key
	 * @return
	 */
	public static String getCookie(HttpServletRequest request, String key) {
		try {
			Cookie[] cookies = request.getCookies();
			if ((cookies == null) || (cookies.length == 0)) {
				return null;
			}
			for (Cookie cooky : cookies) {
				if (cooky.getName().equals(key)) {
					return cooky.getValue();
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return null;
	}
	
	/**
	 * 取得cookie生存时间
	 * @param request
	 * @param key
	 * @return
	 */
	public static int getCookieMaxAge(HttpServletRequest request, String key){
		try {
			Cookie[] cookies = request.getCookies();
			if ((cookies == null) || (cookies.length == 0)) {
				return 0;
			}
			for (Cookie cooky : cookies) {
				if (cooky.getName().equals(key)) {
					return cooky.getMaxAge();
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return 0;
		
	}
	
	/**
	 * 从user cookie中取得sessionId
	 * @param request
	 * @return
	 */
	public static String getSessionIdFromCookie(HttpServletRequest request, HttpServletResponse response){
		String[] strs = parseCookieValue(request, response);
		if(ArrayUtils.isEmpty(strs)){
			return "";
		}
		try {
			return SecurityUtil.base64Decode(strs[2]);
		} catch (NumberFormatException e) {
			return "";
		}
	}
	
	/**
	 * 从user cookie中取得userId
	 * @param request
	 * @return
	 */
	public static long getUserIdFromCookie(HttpServletRequest request, HttpServletResponse response){
		String[] strs = parseCookieValue(request, response);
		if(ArrayUtils.isEmpty(strs)){
			return 0;
		}
		try {
			return Long.valueOf(SecurityUtil.base64Decode(strs[0]));
		} catch (NumberFormatException e) {
			return 0;
		}
	}
	
	/***
	 * 解析logon cookie
	 * @param request
	 * @return
	 */
	public static Map<String, String> parseLogonCookieValue(HttpServletRequest request, HttpServletResponse response){
		String cookieValue = CookieUtil.getCookie(request, COOKIE_KEY);
		if (!StringUtils.isEmpty(cookieValue)) {
			try {
				cookieValue = URLDecoder.decode(cookieValue, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				return null;
			}
		} else {
			return null;
		}
		String[] strs = cookieValue.split("\\|");
		if (strs.length != 4) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		sb.append(strs[0]).append(SPLITER).append(strs[1]).append(SPLITER).append(strs[2]);
		String sign = SecurityUtil.md5(sb.toString() + KEY);
		if (sign.equals(strs[3])) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("userId", SecurityUtil.base64Decode(strs[0]));
			map.put("nickName", SecurityUtil.base64Decode(strs[1]));
			map.put("sessionId", SecurityUtil.base64Decode(strs[2]));
			return map;
		}else{
			setCookie(response, DOMAIN, COOKIE_KEY, "", COOKIE_LIVE_SESSION);
			return null;
		}
	}
	
	/**
	 * 解析cookieValue
	 * @param request
	 * @return NULL cookie失效
	 */
	private static String[] parseCookieValue(HttpServletRequest request, HttpServletResponse response){
		String cookieValue = CookieUtil.getCookie(request, COOKIE_KEY);
		if (null != cookieValue) {
			try {
				cookieValue = URLDecoder.decode(cookieValue, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				return null;
			}
		} else {
			return null;
		}

		String[] strs = cookieValue.split("\\|");

		if (strs.length != 4) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		sb.append(strs[0]).append(SPLITER).append(strs[1]).append(SPLITER).append(strs[2]);
		String sign = SecurityUtil.md5(sb.toString() + KEY);
		if (sign.equals(strs[3])) {
			return strs;
		}else{
			setCookie(response, DOMAIN, COOKIE_KEY, "", COOKIE_LIVE_SESSION);
			return null;
		}
		
	}
	
}